See how the linux kernel project compares to other vendors in security performance
In the Linux kernel, the following vulnerability has been resolved:
selinux: require every boolean value to be defined
pbools.nprim comes from the policy image independently of how many booleans follow it, and condindexbool() fills boolvaltostruct[] at value - 1, so a count larger than the values present leaves NULL entries. Every user of that array then walks it by index and dereferences each entry: condevaluateexpr() on the access-vector path, securitygetbools() and securitygetboolvalue() behind selinuxfs, and securitysetbools(). A sparse class value is absorbed by policydbclassisvalid() and its siblings; booleans have no such predicate, and no consumer that could use one.
Reject a boolean value that no boolean defines, once, where the array is built. Conforming policies define every boolean they declare and are unaffected.
In the Linux kernel, the following vulnerability has been resolved:
usb: xhci: bail out of setup if the controller is inaccessible
xhcigensetup() locates the operational registers using the capability length read from the very first register:
xhci->opregs = hcd->regs + HCLENGTH(readl(&xhci->capregs->hccapbase));
If the controller is dead or has dropped off the bus, that read returns ~0, HCLENGTH() truncates it to 0xff, and opregs ends up 0xff bytes past the page-aligned MMIO base, i.e. unaligned. The first access through it, xhcihalt() -> xhcihandshake() reading opregs->status, is then an unaligned readl() on device memory. arm64 faults on unaligned device accesses, so instead of xhcihandshake() catching the all-ones value and returning -ENODEV, setup oopses:
xhci-pci-renesas 0005:08:00.0: Unable to change power state from D3cold to D0, device inaccessible xhci-pci-renesas 0005:08:00.0: xHCI Host Controller xhci-pci-renesas 0005:08:00.0: new USB bus registered, assigned bus number 1 Unable to handle kernel paging request at virtual address ffff80030a770103 ESR = 0x0000000096000021 FSC = 0x21: alignment fault Internal error: Oops: 0000000096000021 [#1] SMP pc : xhcihalt [xhcihcd] Call trace: xhcihalt xhcigensetup xhcipcisetup usbaddhcd usbhcdpciprobe xhcipcicommonprobe xhcipcirenesasprobe
This was hit with a Renesas uPD720201 that failed to power up ("Unable to change power state from D3cold to D0, device inaccessible") yet still reached the HCD probe path.
Read the capability register once, and if it reads back the all-ones value (as xhcihandshake() and xhcireset() already test for), abort setup with -ENODEV before opregs is derived from it. Reading it once also avoids re-reading a register that may change under a concurrent hot-removal.
In the Linux kernel, the following vulnerability has been resolved:
gpio: sloppy-logic-analyzer: fix use-after-free via debugfs trigger on unbind
The "trigger" debugfs file has a hand-rolled ->write handler (triggerwrite()) that dereferences the per-device gpiolapollpriv. The file is created with debugfscreatefileunsafe(), and the handler never takes a debugfs reference. Nothing keeps the object alive while the handler runs.
priv is allocated with devmkzalloc(). devres frees it when the platform device is unbound. debugfscreatefileunsafe() installs no fullproxy wrapper, so debugfsremoverecursive() in gpiolapollremove() does not wait for an in-flight triggerwrite(). The bloblock taken there does not help, because triggerwrite() never takes it. A write that races an unbind therefore writes into freed memory:
triggerwrite() gpiolapollremove() priv = m->private buf = memdupuser() [may sleep] mutexlock(&priv->bloblock) debugfsremoverecursive() [no wait] mutexunlock(&priv->bloblock) (remove returns; devres frees priv) priv->trigdata = buf <-- use-after-free write priv->triglen = count
The race is reachable by root via /sys/bus/platform/drivers/gpio-sloppy-logic-analyzer/unbind.
Create "trigger" with debugfscreatefile() instead. Its fullproxy wrapper makes debugfsremoverecursive() drain any in-flight ->write before it returns.
The use-after-free is confirmed under KASAN with a minimal reproducer of the same debugfscreatefileunsafe() plus devmkzalloc() pattern (available on request); it produces a slab-use-after-free write in the handler.
In the Linux kernel, the following vulnerability has been resolved:
net/openvswitch: check Ethernet header length in keyextract()
When a packet arrives on an ARPHRDNONE device (e.g. TUN), ovsflowkeyextract() trusts the user-provided skb->protocol field: if it is ETHPTEB, the packet is classified as MACPROTOETHERNET and keyextract() is called without ensuring the skb has ETHHLEN (14) bytes of linear data. keyextract() unconditionally pulls 2 ETHALEN bytes for MAC addresses and parseethertype() pulls 2 more, either of which triggers a kernel BUG in skbpull() when the linear area is too small.
kernel BUG at include/linux/skbuff.h:2848! RIP: 0010:keyextract+0xa7e/0xd90 net/openvswitch/flow.c:933 ovsflowkeyextract+0x419/0xa70 ovsvportreceive+0x222/0x390 netdevframehook+0x3e0/0x630 tungetuser+0x2d0c/0x38e0
Fixed by calling checkheader() in keyextract() before accessing the Ethernet header.
In the Linux kernel, the following vulnerability has been resolved:
scsi: mpi3mr: Fix potential deadlock in mpi3mrfaultueventemit
mpi3mrfaultueventemit() runs from the fault watchdog and reset paths where host I/O may already be blocked. GFPKERNEL allocations here, both the local kzallocobj() and the ones inside kobjectueventenv() itself, can trigger reclaim that waits on that blocked I/O and deadlock.
Use memallocnoiosave()/restore() to cover the whole call instead of just the local allocation.
In the Linux kernel, the following vulnerability has been resolved:
qede: sync udptunnel ports outside qedelock in the recovery path
A TX timeout on a qede NIC that has VXLAN/GENEVE tunnel ports configured wedges the rtnetlink control plane of the whole machine:
NETDEV WATCHDOG: ens6f1 (qede): transmit queue 2 timed out 10226 ms [qedetxtimeout:586(ens6f1)]TX timeout on queue 2! [qederecoveryhandler:2665(ens6f0)]Starting a recovery process
The recovery path deadlocks on the driver's own mutex:
qedesptask rtnllock() mutexlock(&edev->qedelock) <- taken qederecoveryhandler qedeload udptunnelnicresetntf udptunnelnicdevicesync info->synctable == qedeudptunnelsync mutexlock(&edev->qedelock) <- same task: deadlock
The mutex is not recursive, so the kworker blocks on itself with rtnllock held, and neither lock is ever released. Every task that calls rtnllock() afterwards (ip, ovs-vswitchd, lldpad, IPv6 addrconf, sshd) blocks forever while the node still answers ping. In a vmcore from an affected production node rtnlmutex.owner decodes to the very kworker blocked at the innermost mutexlock() above.
Re-sync the tunnel ports from qedesptask() after the internal lock is dropped, still under rtnllock as the udptunnel API requires. This mirrors qedeopen(), which calls udptunnelnicresetntf() under rtnl without the internal lock.
qederecoveryhandler() now returns whether it has successfully reloaded an open device, and the caller re-syncs the ports only in that case. This keeps the old gating exactly: a device that was down or a failed recovery returns false, as those paths never reached the udptunnelnicresetntf() call before either.
This was the only user of the qedelock()/qedeunlock() helpers, so remove them.
In the Linux kernel, the following vulnerability has been resolved:
wifi: mac80211: fix tidtx use-after-free on BA session stop
ieee80211stoptxbacb() hands tidtx to kfreercu() through ieee80211removetidtx(), and then reads tidtx->ndp after dropping sta->lock:
ieee80211removetidtx(sta, tid); / kfreercu(tidtx, rcuhead) / ... spinunlockbh(&sta->lock);
if (starttxq) ieee80211aggstarttxq(sta, tid, false);
if (senddelba) ieee80211senddelba(..., tidtx->ndp);
That read is not covered by an RCU read-side critical section, and it runs in preemptible process context: both callers hold the wiphy mutex, reaching it either from the ieee80211basessionwork() wiphy work or from ieee80211stateardownBAsessions() during station teardown. Softirqs can run in that window too, both from the localbhenable() that ends ieee80211aggstarttxq() and from any interrupt exit, so the RCU callback can free tidtx before the read.
Driving the function from a test module with the grace period forced into that window, KASAN reports the read, and the free arrives on the ordinary RCU softirq path:
BUG: KASAN: slab-use-after-free in ieee80211stoptxbacb+0x3cd/0x400 Read of size 1 at addr ffff888002b9f52e by task kworker/0:1/10 [...] Freed by task 57: kasanslabfree+0x47/0x70 rcufreesheafprepare+0x70/0x250 rcufreesheafnobarn+0x18/0x40 rcucore+0x426/0x1310 handlesoftirqs+0x144/0x590 irqexitrcu+0xea/0x150 irqexitrcu+0x9/0x20 sysvecapictimerinterrupt+0x6b/0x80 asmsysvecapictimerinterrupt+0x1a/0x20
senddelba is only set when txstop is set, which happens for AGGSTOPLOCALREQUEST alone, so this is reached on local teardown - session idle timeout, PTK rekey, suspend, HW reconfig - and not from a peer's DELBA.
Read ndp into a local before the session is freed, while sta->lock is still held. tidtx->ndp has a single writer, in ieee80211txbasessionhandlestart(), which cannot run concurrently here: both paths are serialised by the wiphy mutex, and the session is already marked HTAGGSTATESTOPPING at this point. tidtx->ndp is also the only tidtx dereference left after ieee80211removetidtx() in this function.
[move/change the comment a bit to be more general not just on ndp, initialize ndp directly]
In the Linux kernel, the following vulnerability has been resolved:
wifi: ath12k: fix memory leak in ath12kwifi7dprxhverifytkipmic()
In ath12kwifi7dprxhverifytkipmic(), the call to ath12kdprxchecknwifihdrlenvalid() may return false when the NWIFI header length is invalid, causing the function to abort early with -EINVAL.
When this happens, the error propagates to ath12kwifi7dprxhdefrag(), which clears firstfrag by setting it to NULL. As a result, the corresponding MSDU is no longer referenced by the defragmentation path and is never freed.
This leads to a memory leak for the affected MSDU on this error path. Proper cleanup is required to ensure the MSDU is released when header validation fails during TKIP MIC verification.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPLV1.0V2.0SILICONZ-1.115823.3
In the Linux kernel, the following vulnerability has been resolved:
ext4: validate donor file superblock early in EXT4IOCMOVEEXT
Reject the EXT4IOCMOVEEXT ioctl early if the donor file does not belong to the same superblock as the original file. Currently, this validation is performed inside ext4moveextents() by mextcheckvalidity(), but only after locktwonondirectories() has already acquired the inode locks. When the donor fd refers to a file on a different filesystem (e.g., overlayfs), this late validation creates a circular lock dependency:
CPU0 (overlayfs write) CPU1 (ext4 ioctl) ---- ---- inodelock(ovlinode) mntwantwritefile(filp) sbstartwrite(ext4sb) [sbwriters] backingfilewriteiter() vfsiterwrite(realfile) filestartwrite(realfile) sbstartwrite(ext4sb) [blocked by freeze] locktwonondirectories() inodelock(ovlinode) [blocked]
With a concurrent freeze operation holding sbwriters write side, this forms a deadlock cycle: CPU0 waits for freeze to complete, freeze waits for CPU1's sbwriters reader to exit, CPU1 waits for CPU0's inode lock.
Since EXT4IOCMOVEEXT exchanges physical extents between two files, it fundamentally requires both files to reside on the same ext4 filesystem. Moving the superblock check before any lock acquisition is both semantically correct and eliminates the circular dependency by ensuring that cross-filesystem donor fds are rejected before sbwriters or inode locks are taken.
In the Linux kernel, the following vulnerability has been resolved:
rtc: msc313: fix NULL deref in shared IRQ handler at probe
msc313rtcprobe() calls devmrequestirq() with IRQFSHARED and &pdev->dev as the cookie, but platformsetdrvdata() is only called later after the clock setup. With a shared IRQ line, another device on the same line can trigger the handler in that window. The handler does devgetdrvdata() on the cookie, gets NULL, and dereferences priv->rtcbase in interrupt context.
Pass priv as the cookie directly so the handler reads it from devid without the lookup, removing the dependency on probe order.
In the Linux kernel, the following vulnerability has been resolved:
fbdev: tdfxfb: fix potential memory leak in tdfxfbprobe()
In tdfxfbprobe(), the memory allocated for modelist using fbvideomodetomodelist() when CONFIGFB3DFXI2C is defined, is not freed in the subsequent error paths. Fix that by calling fbdestroymodelist().
In the Linux kernel, the following vulnerability has been resolved:
batman-adv: frag: fix primaryif leak on failed linearization
If the skb has a fraglist, it must be linearized before it can be split using skbsplit(). But when this step failed, it must not only free the skb but also take care of the reference to the already found primaryif.
In the Linux kernel, the following vulnerability has been resolved:
dm thin metadata: fix metadata snapshot consistency on commit failure
reservemetadatasnap() and releasemetadatasnap() modify the superblock's heldroot directly in the blockmanager's buffer. If the subsequent metadata commit fails, the heldroot gets flushed to disk through the aborttransaction path, resulting in inconsistent metadata.
Reproducer 1: reservemetadatasnap()
1. Create a 2 MiB metadata device and make the region after the 14th block inaccessible, to trigger metadata commit failure in the subsequent reservemetadatasnap operation. The 14th block will be the shadow destination for the index block.
dmsetup create tmeta --table "0 112 linear /dev/sdc 0 112 3984 error"
2. Create a 16 MiB thin-pool
dmsetup create tdata --table "0 32768 zero" dd if=/dev/zero of=/dev/mapper/tmeta bs=4k count=1 dmsetup create tpool --table "0 32768 thin-pool /dev/mapper/tmeta \ /dev/mapper/tdata 128 0 1 skipblockzeroing"
3. Take a metadata snapshot to trigger metadata commit failure and transaction abort. However, the heldroot is written to disk, breaking metadata consistency.
dmsetup message tpool 0 "reservemetadatasnap"
thincheck v1.2.2 result:
Bad reference count for metadata block 6. Expected 2, but space map contains 1. Bad reference count for metadata block 7. Expected 2, but space map contains 1. Bad reference count for metadata block 13. Expected 1, but space map contains 0.
Reproducer 2: releasemetadatasnap()
1. Create a 2 MiB metadata device and make the region after the 16th block inaccessible, to trigger metadata commit failure in the subsequent releasemetadatasnap operation. The 16th block will be the shadow destination for the index block.
dmsetup create tmeta --table "0 128 linear /dev/sdc 0 128 3968 error"
2. Create a 16 MiB thin-pool
dmsetup create tdata --table "0 32768 zero" dd if=/dev/zero of=/dev/mapper/tmeta bs=4k count=1 dmsetup create tpool --table "0 32768 thin-pool /dev/mapper/tmeta \ /dev/mapper/tdata 128 0 1 skipblockzeroing"
3. Reserve then release the metadata snapshot, to trigger metadata commit failure and transaction abort. The heldroot gets removed from the on-disk superblock, causing inconsistent metadata.
dmsetup message tpool 0 "reservemetadatasnap" dmsetup message tpool 0 "releasemetadatasnap"
thincheck v1.2.2 result:
Bad reference count for metadata block 6. Expected 1, but space map contains 2. Bad reference count for metadata block 7. Expected 1, but space map contains 2. 1 metadata blocks have leaked.
Fix by deferring the heldroot update to commit time.
Additionally, move the existing-snapshot check in reservemetadatasnap before the shadow operation to avoid unnecessary work. In releasemetadatasnap, clear pmd->heldroot before btree deletion so partial failure leaks blocks rather than leaving a stale reference, and unlock the snapshot block before decrementing its refcount.
In the Linux kernel, the following vulnerability has been resolved:
net: sit: require CAPNETADMIN in the device netns for changelink
ipip6changelink() operates on at most two netns, devnet(dev) and the tunnel link netns t->net. They differ once the device is created in or moved to a netns other than the one the request runs in. The rtnl changelink path checks CAPNETADMIN only against devnet(dev), so a caller privileged there but not in t->net can rewrite a tunnel that lives in t->net.
Gate ipip6changelink() on rtnldevlinknetcapable() at its top, before any attribute is parsed. sit was the one tunnel type not covered by the recent series that added this check to the other changelink() handlers.
In the Linux kernel, the following vulnerability has been resolved:
net/sched: schmultiq: Replace direct dequeue call with peek and qdiscdequeuepeeked
multiqdequeue() takes a packet from a band's child with a direct ->dequeue() call after multiqpeek() peeked it. When the child is non-work-conserving the peek stashes the skb in the child's gsoskb, so the direct dequeue returns a different skb and orphans the stash, desyncing the child's qlen/backlog. With a qfq child reached through a peeking parent (e.g. tbf) this re-enters the child on an emptied list and dereferences NULL, panicking the kernel from softirq on ordinary egress.
Take the packet through qdiscdequeuepeeked(), as schprio already does and as schred and schsfb were just fixed to do. The helper is a no-op when the child has no stash, so a work-conserving child is unaffected.
In the Linux kernel, the following vulnerability has been resolved:
scsi: target: iscsi: Validate CHAPR length before base64 decode
chapservercomputehash() allocates clientdigest as kzalloc(chap->digestsize) and then, for BASE64-encoded responses, passes chapr directly to chapbase64decode() without checking whether the input length could produce more than digestsize bytes of output.
chapbase64decode() writes to the destination unconditionally as long as there is input to consume. With MAXRESPONSELENGTH set to 128 and the "0b" prefix stripped by extractparam(), up to 127 base64 characters can reach the decoder. 127 characters decode to 95 bytes. For SHA-256 (digestsize=32) this overflows clientdigest by 63 bytes; for MD5 (digestsize=16) the overflow is 79 bytes.
The length check at line 344 fires after the write has already happened.
The HEX branch in the same switch statement already validates the length up front. Apply the same approach to the BASE64 branch: strip trailing base64 padding characters, then reject any input whose data length exceeds DIVROUNDUP(digestsize 4, 3) before calling the decoder.
Stripping trailing '=' before the comparison handles both padded and unpadded encodings. chapbase64decode() already returns early on '=', so the full original string is still passed to the decoder unchanged.
The mutual CHAP path decodes CHAPC into initiatorchgbinhex, which is kzalloc(CHAPCHALLENGESTRLEN). extractparam() caps initiatorchg at CHAPCHALLENGESTRLEN characters, so at most CHAPCHALLENGESTRLEN-1 base64 characters reach the decoder. The maximum decoded size, DIVROUNDUP((CHAPCHALLENGESTRLEN-1) 3, 4), is less than CHAPCHALLENGESTRLEN, so no overflow is possible there. A comment is added at the call site to document this.
In the Linux kernel, the following vulnerability has been resolved:
NFSv4/pNFS: reject zero-length raddr in nfs4decodempdsaddr
nfs4decodempdsaddr() decodes the rnetid and raddr opaques of a netaddr4 from a GETDEVICEINFO multipath-DS body, then immediately calls strrchr(buf, '.') to locate the port separator. Both decodes use xdrstreamdecodestringdup(), and the current code checks only "nlen < 0" / "rlen < 0" before dereferencing the returned string.
When the on-wire opaque has length zero, xdrstreamdecodeopaqueinline() returns 0 and xdrstreamdecodestringdup() falls through to its "str = NULL; return ret" tail, leaving buf NULL with a return value of 0. The "< 0" check does not catch this, and the next line is strrchr(NULL, '.'), a kernel NULL pointer dereference reachable from any pNFS-flexfile client mounted against a malicious or compromised metadata server.
Reject the zero-length cases explicitly so the decoder fails with -EBADMSG (treated as a malformed GETDEVICEINFO body) instead of panicking the client.
In the Linux kernel, the following vulnerability has been resolved:
f2fs: validate orphan inode entry count
f2fsrecoverorphaninodes() trusts the orphan block entrycount when replaying orphan inodes from the checkpoint pack. A corrupted entrycount larger than F2FSORPHANSPERBLOCK makes the recovery loop read past the ino[] array and interpret footer or following data as inode numbers.
On a crafted image, mounting an unpatched kernel can drive orphan recovery into f2fsbugon() and panic the kernel. Validate entrycount before consuming entries so corrupted checkpoint data fails the mount with -EFSCORRUPTED and requests fsck instead.
Set ERRORINCONSISTENTORPHAN as well, so the corruption reason can be recorded in the superblock serrors[] field. This gives fsck a persistent hint even though mount-time orphan recovery failure may leave no chance to persist SBINEEDFSCK through a checkpoint.
In the Linux kernel, the following vulnerability has been resolved:
exfat: fix potential use-after-free in exfatfinddirentry()
In exfatfinddirentry(), the bufferhead obtained from exfatgetdentry() is released with brelse(bh) before the fall-through TYPEEXTEND branch reads the directory entry through ep (which points into bh->bdata):
brelse(bh); if (entrytype == TYPEEXTEND) { ... len = exfatextractuniname(ep, entryuniname); ... }
After brelse() drops our reference, nothing guarantees that the underlying page backing bh->bdata remains valid for the subsequent exfatextractuniname() read. This is the same pattern fixed in commit fc961522ddbd ("exfat: Fix potential use after free in exfatloadupcasetable()").
Move brelse(bh) so it runs after ep is no longer dereferenced on each branch.
Confirmed on QEMU x8664 with CONFIGKASAN=y + CONFIGDEBUGPAGEALLOC=y + CONFIGPAGEPOISONING=y on linux-next, using a crafted exFAT image (long filename with same-hash collisions forcing the TYPEEXTEND path). With a debug-only invalidatebdev() inserted between brelse(bh) and the ep read to make the stale-deref window deterministic, the unpatched kernel faults:
BUG: KASAN: use-after-free in exfatfinddirentry+0x133b/0x15a0 BUG: unable to handle page fault for address: ffff88801a5fa0c2 Oops: 0000 [#1] SMP DEBUGPAGEALLOC KASAN NOPTI RIP: 0010:exfatfinddirentry+0x1188/0x15a0
With this patch applied, the same instrumented harness completes cleanly under the same sanitizer stack. I have not reproduced a crash on an uninstrumented kernel under ordinary reclaim; the instrumented A/B establishes the lifetime violation and that the patch closes it, not an unaided triggerability claim.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: conntrackirc: fix possible out-of-bounds read
When parsing fails after we've matched the command string we should bail out instead of trying to match a different command.
This helper should be deprecated, given prevalence of TLS I doubt it has any relevance in 2026.
In the Linux kernel, the following vulnerability has been resolved:
PCI: dwc: ep: Prevent changing BAR size/flags in pciepcsetbar()
In commit 4284c88fff0e ("PCI: designware-ep: Allow pciepcsetbar() update inbound map address") setbar() was modified to support dynamically changing the backing physical address of a BAR that was already configured.
This means that setbar() can be called twice, without ever calling clearbar() (as calling clearbar() would clear the BAR's PCI address assigned by the host).
This can only be done if the new BAR size/flags does not differ from the existing BAR configuration. Add these missing checks.
If we allow setbar() to set e.g. a new BAR size that differs from the existing BAR size, the new address translation range will be smaller than the BAR size already determined by the host, which would mean that a read past the new BAR size would pass the iATU untranslated, which could allow the host to read memory not belonging to the new struct pciepfbar.
While at it, add comments which clarifies the support for dynamically changing the physical address of a BAR. (Which was also missing.)